進入各求職平台,搜尋前端關鍵字為例,觀察資料來源以及類型 (使用平台預設條件或排序,不另做設定)
網頁:https://www.104.com.tw/jobs/search/?keyword=前端&order=1&jobsource=2018indexpoc&ro=0
預設以符合度排序,屬於 Server Side Render,可使用 Axios + cheerio
各項職缺提供的資訊:
網頁:https://www.yourator.co/jobs?term[]=前端
預設以相關程度排序,有 API,可使用 Axios
各項職缺提供的資訊:
API:https://www.yourator.co/api/v4/jobs?page=1&term[]=前端
網頁:https://www.cakeresume.com/jobs/前端
預設以熱門程度排序,屬於 Server Side Render,可使用 Axios + cheerio
各項職缺提供的資訊:
項目 | 104 數字網 | yourator | CakeResume |
---|---|---|---|
職稱 | v | v | v |
公司名稱 | v | v | v |
公司 Logo | v | v | |
公司產業 | v | ||
職缺描述 | v | v | |
工作地點 | v | v | v |
工作經歷 | v | v | |
薪資範圍 | - | v | v |
其他標籤 | v | v | v |
學歷要求 | v | ||
需求人數 | v | ||
管理責任 | v | ||
瀏覽次數 | v | ||
更新狀態 | v | v | |
雇主活躍度 | v |
JobScanner 需要的資訊,包含:職稱、公司名稱、Logo、職缺描述、工作地點、薪資、其他標籤、職缺連結 (104:無 Logo 以灰底圖替代;薪資資訊從其他標籤取得)
{
"name": "前端工程師 (Front-end Engineer)",
"companyName": "xxx有限公司",
"companyLogo": "https://xxx/xxx.png",
"description": "xxxxx",
"location": "xxxx",
"salary": "NT$ 50,000 - 65,000 (月薪)",
"tags": ["JavaScript", "ReactJS", "Git", "Redux", "前端工程師"],
"url": "https://www.xxxxx",
}
觀察求職平台是如何載入更多職缺
進入網頁:https://www.104.com.tw/jobs/search/?keyword=前端&order=1&jobsource=2018indexpoc&ro=0
向下捲動會自動載入更多職缺
網址會被替換成:https://www.104.com.tw/jobs/search/?ro=0&kwop=7&keyword=前端&expansionType=area,spec,com,job,wf,wktm&order=15&asc=0&page=2&mode=s&jobsource=2018indexpoc&langFlag=0&langStatus=0&recommendJob=1&hotJob=1
*省略部分 query string 結果大致相同,例如:https://www.104.com.tw/jobs/search/?ro=0&kwop=7&keyword=前端&expansionType=area,spec,com,job,wf,wktm&order=15&asc=0&page=2&mode=s&jobsource=2018indexpoc&langFlag=0&langStatus=0&recommendJob=1&hotJob=1
改為https://www.104.com.tw/jobs/search/?keyword=前端&order=1&jobsource=2018indexpoc&ro=0&page=2
進入網頁:https://www.yourator.co/jobs?term[]=%E5%89%8D%E7%AB%AF
向下捲動會自動載入更多職缺
API 會 call https://www.yourator.co/api/v4/jobs?page=2&term[]=前端
進入網頁:https://www.cakeresume.com/jobs/前端
捲至底部時,會有 Pagination 可以做切換,點擊第二頁後
網址會更改為:https://www.cakeresume.com/jobs/前端?page=2
三個求職平台都是改變 query String 中 page 的值
以關鍵字 前端
,取得 104 求職平台前三頁的資料為例:
先確認 robots.txt 內容
使用 Axios + cheerio,透過 class、attribute 選取元素,取得資料內容,並存入 json
const fs = require("fs"),
axios = require("axios"),
cheerio = require("cheerio");
let jobList = [],
page = 1,
baseUrl = `https://www.104.com.tw/jobs/search/`,
keyword = '前端';
const fetchJob = async(keyword, page = 1) => {
console.log(`Fetch page data --- Page ${page}`);
let url =`${baseUrl}?order=1&jobsource=2018indexpoc&ro=0&keyword=${keyword}&page=${page}`
let data = await axios.get(url);
let $ = cheerio.load(data.data);
$('.job-list-item').each(function () {
let $this = $(this);
let name = $this.find('.b-tit a.js-job-link').text(),
companyName = $this.find('.b-list-inline li:nth-child(2) > a').text(),
description = $this.find('.job-list-item__info').text(),
location = $this.find('.job-list-intro > li:first-child').text(),
url = $this.find('.b-tit a.js-job-link').attr("href"),
salary = '',
tags = [];
$this.find('.job-list-tag a').each(function () {
let $tag = $(this);
if ($tag.text().includes('薪')) salary = $tag.text();
tags.push($tag.text());
});
url = url && url.replace(/^\/\//, '');
jobList.push({name, companyName, companyLogo: '', description, location, salary, tags, url });
});
}
const writeFile = (fileName, data) => {
fs.writeFile(fileName, data, "utf8", function (err) {
if (err) {
console.log("Something error while writing JSON Object to File.");
return console.log(err);
}
console.log("JSON file has been saved.");
});
}
const init = async() => {
do {
await fetchJob(keyword, page);
page += 1;
} while(page <= 3)
const result = jobList.filter(item => item.name.includes(keyword));
writeFile('104.json', JSON.stringify(result));
}
init();
薪
關鍵字,作為 salary 資料